package com.dilidili.service;

import cn.hutool.core.util.RandomUtil;
import com.alibaba.nacos.common.utils.UuidUtils;
import com.dilidili.config.OssConfig;
import com.dilidili.utils.FileUploadResult;
import com.aliyun.oss.OSS;
import com.aliyun.oss.model.ListObjectsRequest;
import com.aliyun.oss.model.OSSObject;
import com.aliyun.oss.model.OSSObjectSummary;
import com.aliyun.oss.model.ObjectListing;
import com.util.TransferUtil;
import it.sauronsoftware.jave.Encoder;
import it.sauronsoftware.jave.EncoderException;
import it.sauronsoftware.jave.MultimediaInfo;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.fileupload.FileItem;
import org.apache.commons.fileupload.FileItemFactory;
import org.apache.commons.fileupload.disk.DiskFileItem;
import org.apache.commons.fileupload.disk.DiskFileItemFactory;
import org.apache.commons.lang3.RandomUtils;
import org.apache.commons.lang3.StringUtils;
import org.joda.time.DateTime;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.scheduling.annotation.Async;
import org.springframework.stereotype.Service;
import org.springframework.web.multipart.MultipartFile;
import org.springframework.web.multipart.MultipartHttpServletRequest;
import org.springframework.web.multipart.commons.CommonsMultipartFile;

import javax.annotation.Resource;
import javax.servlet.http.HttpServletRequest;
import java.io.*;
import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.Date;
import java.util.List;
import java.util.UUID;
import java.util.concurrent.TimeUnit;

import static com.dilidili.utils.VideoUtil.getVideoPicture;

/**
 * <p>Title: 文件上传服务类</p>
 * <p>Description: </p>
 * <p>Copyright: Copyright (c) 2020</p>
 * <p>Company: http://www.ubisys.com.cn/</p>
 *
 * @Auther: cw
 * @Date: 2020/9/3 20:43
 */
@Service
@Slf4j
public class FileUpLoadService {
    @Resource
    RedisTemplate redisTemplate;
    // 允许上传的格式
    private static final String[] IMAGE_TYPE = new String[]{".bmp", ".jpg",
            ".jpeg", ".gif", ".png",".flv",".mp4",".avi",".wmv",".mov",".webm",".mpeg4",".ts",".rm",".rmvb",".mkv",".m4v"};
//    .mp4,.flv,.avi,.wmv,.mov,.webm,.mpeg4,.ts,.mpg,.rm,.rmvb,.mkv,.m4v
    @Autowired
    private OSS ossClient;
    @Autowired
    private OssConfig aliyunConfig;
 
    /**
     *  文件上传
     * @param uploadFile
     * @return
     */
    public FileUploadResult upload(MultipartFile uploadFile) throws Exception {
        // 校验图片格式
        boolean isLegal = false;
        for (String type : IMAGE_TYPE) {
            if (StringUtils.endsWithIgnoreCase(uploadFile.getOriginalFilename(),
                    type)) {
                isLegal = true;
                break;
            }
        }
        //封装Result对象，并且将文件的byte数组放置到result对象中
        FileUploadResult fileUploadResult = new FileUploadResult();
        if (!isLegal) {
            fileUploadResult.setStatus("error");
            return fileUploadResult;
        }
        //文件新路径
        String fileName = uploadFile.getOriginalFilename();
        String filePath = getFilePath(fileName);
        // 上传到阿里云
        try {
            ossClient.putObject(aliyunConfig.getBucketName(), filePath, new
                    ByteArrayInputStream(uploadFile.getBytes()));
        } catch (Exception e) {
            e.printStackTrace();
            //上传失败
            fileUploadResult.setStatus("error");
            return fileUploadResult;
        }
        fileUploadResult.setStatus("done");
        fileUploadResult.setResponse("success");
        //this.aliyunConfig.getUrlPrefix() + filePath 文件路径需要保存到数据库
        fileUploadResult.setName(filePath);
        fileUploadResult.setUid(String.valueOf(System.currentTimeMillis()));
        return fileUploadResult;
    }

    public Object a(MultipartFile uploadFile, HttpServletRequest request) throws Exception {
        FileUploadResult res = upload(uploadFile);
        MultipartHttpServletRequest multipartRequest = (MultipartHttpServletRequest) request;
        SimpleDateFormat dateformat = new SimpleDateFormat("yyyy/MM/dd/HH");
        /** 构建文件保存的目录* */
        String logoPathDir = "/business/shops/upload/"
                + dateformat.format(new Date());
        /** 得到文件保存目录的真实路径* */
        String logoRealPathDir = request.getSession().getServletContext()
                .getRealPath(logoPathDir);
        /** 根据真实路径创建目录* */
        File logoSaveFile = new File(logoRealPathDir);
        if (!logoSaveFile.exists())
            logoSaveFile.mkdirs();
        /** 页面控件的文件流* */
        MultipartFile multipartFile = multipartRequest.getFile("file");
        /** 获取文件的后缀* */
        String suffix = multipartFile.getOriginalFilename().substring(
                multipartFile.getOriginalFilename().lastIndexOf("."));
        /** 使用UUID生成文件名称* */
        String logImageName = UUID.randomUUID().toString() + suffix;// 构建文件名称
        /** 拼成完整的文件保存路径加文件* */
        String fileName = logoRealPathDir + File.separator + logImageName;
        File file = new File(fileName);
        try {
            multipartFile.transferTo(file);
        } catch (IllegalStateException e) {
            e.printStackTrace();
        } catch (IOException e) {
            e.printStackTrace();
        }
        /** 打印出上传到服务器的文件的绝对路径* */
        System.out.println("****************" + fileName + "**************");
        log.info(fileName);
//        long urlVideoSecond = getURLVideoSecond(fileName);
//        System.out.println(urlVideoSecond);
        int i = fileName.lastIndexOf(".");
        String substring = fileName.substring(0, i);
        System.out.println("substring+:---------------------" + substring);
        String s1 = substring + "_480_320.mp4";

        Boolean transform = TransferUtil.transform("E:\\百度网盘传输\\ffmpeg-20200220-56df829-win64-static\\bin\\ffmpeg.exe",
                fileName,
                s1, "480x320");
        System.out.println(transform);
        MultipartFile mulFileByPath = getMulFileByPath(s1);
        FileUploadResult upload3 = upload(mulFileByPath);
        String s2 = substring + "_720_720.mp4";
        Boolean transform1 = TransferUtil.transform("E:\\百度网盘传输\\ffmpeg-20200220-56df829-win64-static\\bin\\ffmpeg.exe",
                fileName,
                s2, "720x720");
        System.out.println(transform1);
        MultipartFile mulFileByPath2 = getMulFileByPath(s2);
        FileUploadResult upload1 = upload(mulFileByPath2);
        String name3 = upload1.getName();
        String s = UuidUtils.generateUuid();
        getVideoPicture(fileName, "F:\\" + s + ".jpg");
        //图片
        MultipartFile mulFileByPath1 = getMulFileByPath("F:\\" + s + ".jpg");
        FileUploadResult upload2 = upload(mulFileByPath1);
        //获取视频时长
        Integer length = getLength(mulFileByPath2);
        ArrayList<Object> objects = new ArrayList();
        objects.add("https://jiangaibo.oss-cn-beijing.aliyuncs.com/"+res.getName());//原皮
        objects.add("https://jiangaibo.oss-cn-beijing.aliyuncs.com/"+upload3.getName());//480_320视频
        objects.add("https://jiangaibo.oss-cn-beijing.aliyuncs.com/"+name3);//720_720视频
        objects.add("https://jiangaibo.oss-cn-beijing.aliyuncs.com/"+upload2.getName());//封面图片
        objects.add(length);
        objects.forEach(System.out::println);
        redisTemplate.opsForValue().set("file", objects, 8000000, TimeUnit.SECONDS);
//        redisTemplate.opsForValue().get("msg_"+id+"_"+acId+"_"+num);
        return res;
    }

    //本地文件转为MultipartFile类型(文件路径)
    private static MultipartFile getMulFileByPath(String picPath) {
        FileItem fileItem = createFileItem(picPath);
        MultipartFile mfile = new CommonsMultipartFile(fileItem);
        return mfile;
    }

    private static FileItem createFileItem(String filePath) {
        FileItemFactory factory = new DiskFileItemFactory(16, null);
        String textFieldName = "textField";
        int num = filePath.lastIndexOf(".");
        String extFile = filePath.substring(num);
        FileItem item = factory.createItem(textFieldName, "text/plain", true,
                "MyFileName" + extFile);
        File newfile = new File(filePath);
        long fileSize = newfile.length();
        int bytesRead = 0;
        byte[] buffer = new byte[(int) fileSize];
        try {
            FileInputStream fis = new FileInputStream(newfile);
            OutputStream os = item.getOutputStream();
            while ((bytesRead = fis.read(buffer, 0, buffer.length)) != -1) {
                os.write(buffer, 0, bytesRead);
            }
            os.close();
            fis.close();
        } catch (IOException e) {
            e.printStackTrace();
        }
        return item;
    }

    //计算视频时间
    private Integer getLength( MultipartFile contentFile) throws EncoderException {
        CommonsMultipartFile cf= (CommonsMultipartFile)contentFile;
        DiskFileItem fi = (DiskFileItem)cf.getFileItem();
        File f = fi.getStoreLocation();
        // 获取视频时长
        Encoder encoder = new Encoder();
        MultimediaInfo m = encoder.getInfo(f);
        long ls = m.getDuration()/1000;
        int hour = (int) (ls/3600);
        int minute = (int) (ls%3600)/60;
        int second = (int) (ls-hour*3600-minute*60);
        //logger.info("视频时长为：{}时{}分{}秒", hour, minute, second);
        String time = hour+":"+minute+":"+second;
        System.out.println(hour);
        System.out.println(minute);
        System.out.println(ls);
        return Integer.parseInt(ls+"");
    }
    /**
     *  通过源文件获取 路径和文件名
     * @param sourceFileName
     * @return
     */
    private String getFilePath(String sourceFileName) {
        DateTime dateTime = new DateTime();
        return "images/" + dateTime.toString("yyyy")
                + "/" + dateTime.toString("MM") + "/"
                + dateTime.toString("dd") + "/" + System.currentTimeMillis() +
                RandomUtils.nextInt(100, 9999) + "." +
                StringUtils.substringAfterLast(sourceFileName, ".");
    }
 
    /**
     * 查看文件列表
     * @return
     */
    public List<OSSObjectSummary> list() {
        // 设置最大个数。
        final int maxKeys = 200;
        // 列举文件。
        ObjectListing objectListing = ossClient.listObjects(new ListObjectsRequest(aliyunConfig.getBucketName()).withMaxKeys(maxKeys));
        List<OSSObjectSummary> sums = objectListing.getObjectSummaries();
        return sums;
    }
 
    /**
     * @desc 删除文件
     */
    public FileUploadResult delete(String objectName) {
        // 根据BucketName,objectName删除文件
        ossClient.deleteObject(aliyunConfig.getBucketName(), objectName);
        FileUploadResult fileUploadResult = new FileUploadResult();
        fileUploadResult.setName(objectName);
        fileUploadResult.setStatus("removed");
        fileUploadResult.setResponse("success");
        return fileUploadResult;
    }
 
    /**
     *   下载文件
     * @param os
     * @param objectName
     * @throws IOException
     */
    public void exportOssFile(OutputStream os, String objectName) throws IOException {
        // ossObject包含文件所在的存储空间名称、文件名称、文件元信息以及一个输入流。
        OSSObject ossObject = ossClient.getObject(aliyunConfig.getBucketName(), objectName);
        // 读取文件内容。
        BufferedInputStream in = new BufferedInputStream(ossObject.getObjectContent());
        BufferedOutputStream out = new BufferedOutputStream(os);
        byte[] buffer = new byte[1024];
        int lenght = 0;
        while ((lenght = in.read(buffer)) != -1) {
            out.write(buffer, 0, lenght);
        }
        if (out != null) {
            out.flush();
            out.close();
        }
        if (in != null) {
            in.close();
        }
    }

    public static void main(String[] args) {
        String s = RandomUtil.randomUUID().substring(9);
        System.out.println(s);
    }

}